package com.chinawayltd.ews.sample.taskCenter;

import com.chinawayltd.ews.sample.mapper.SysTaskLogMapper;
import com.chinawayltd.ews.sample.model.SysTaskLog;
import com.chinawayltd.ews.sample.taskCenter.distributedLock.DistributedLockManager;
import com.chinawayltd.ews.sample.util.spring.SpringContextUtil;
import org.apache.commons.collections.MapUtils;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

public class TaskCreateJob implements Job {

	private static Logger logger = LoggerFactory.getLogger(TaskCreateJob.class);
	private static final String LOCK_PREFIX = "JOB:";

	private DistributedLockManager distributedLockManager;

	public DistributedLockManager getDistributedLockManager() {
		if (this.distributedLockManager == null) {
			distributedLockManager = SpringContextUtil.getBean(DistributedLockManager.class);
		}
		return distributedLockManager;
	}

	public void execute(JobExecutionContext context) throws JobExecutionException {
		Date beginTime = new Date();
		JobDataMap jobMap = context.getJobDetail().getJobDataMap();
		String taskJobName = jobMap.getString(TaskConsts.TASK_JOB_NAME);
		Integer haveLock = MapUtils.getInteger(jobMap, TaskConsts.HAVE_LOCK);

		if(haveLock == 1){
			doJobWithLock(context, beginTime, jobMap, taskJobName);
		}else{
			doJob(context, beginTime, jobMap, taskJobName);
		}
	}

	private void doJobWithLock(JobExecutionContext context, Date beginTime, JobDataMap jobMap, String taskJobName) {
		String lockName = LOCK_PREFIX + taskJobName;
		Integer lockExpireTime = MapUtils.getInteger(jobMap, TaskConsts.LOCK_EXPIRE_TIME);
        if(lockExpireTime == null)lockExpireTime = DistributedLockManager.DEF_EXPIRE_TIME;

		boolean isLock = this.getDistributedLockManager().tryLock(lockName, lockExpireTime);
		if(isLock){
			doJob(context, beginTime, jobMap, taskJobName);
			boolean isReleaseLock = this.getDistributedLockManager().releaseLockDelay(lockName);
			if(!isReleaseLock){
				logger.error("lock【" + lockName + "】释放分布式失败！");
			}
		}else{
			logger.info("JOB【" + taskJobName + "】已被其他定时任务中心节点执行，当前节点跳过当前任务！");
		}
	}

	private void doJob(JobExecutionContext context, Date beginTime, JobDataMap jobMap, String taskJobName) {
		try {
            TaskJob taskJob = SpringContextUtil.getBean(taskJobName);
            taskJob.doJob(context);
            dolog(jobMap, beginTime);
        }catch (Exception e){
            logger.error("JOB【" + taskJobName + "】发生异常：", e);
        }
	}

	private void dolog(JobDataMap jobMap, Date beginTime) {
		boolean haslog = jobMap.getInt(TaskConsts.TASK_HAS_LOG) == 1;
		if(haslog){
            Date endTime = new Date();
            String taskId = jobMap.getString(TaskConsts.TASK_ID);
            SysTaskLog log = new SysTaskLog();
            log.setRelatedTaskDefId(taskId);
            log.setBegtinTime(beginTime);
            log.setEndTime(endTime);
            log.setIsFinish((byte)1);
            log.setCreateTime(endTime);
            log.setUpdateTime(endTime);
            SysTaskLogMapper logMapper = SpringContextUtil.getBean(SysTaskLogMapper.class);
            logMapper.insert(log);
        }
	}

}
